﻿using System;
using System.Linq;
using Engine.Math;
using Engine.Objects.StaticObjects;
using EngineDrawer.Debugging;
using Microsoft.Xna.Framework;
using ThinkDotNetEditorLib.Models.StaticObjects;

namespace ThinkDotNetEditorLib.Models
{
    public class Arena
    {
        public Arena(IGameEditor gameEditor)
        {
            GameEditor = gameEditor;
        }

        #region Public Methods

        public void UnselectAll()
        {
            var boundingBoxDrawer = (BoundingBoxDrawer)GameEditor.XnaGame.Services.GetService(typeof(BoundingBoxDrawer));
            boundingBoxDrawer.Clear();
        }
        public StaticObject SelectObject(Point mousePoint)
        {
            StaticObject clickedObject= GameEditor.World.IntersectWithStaticObjects(GetCursorRay(mousePoint));
            if (clickedObject != null)
            {
                var boundingBoxDrawer = (BoundingBoxDrawer) GameEditor.XnaGame.Services.GetService(typeof (BoundingBoxDrawer));
                BoundingBox boundingBox = clickedObject.InitialBoundingBox.Transform(clickedObject.WorldMatrix);
                if (boundingBoxDrawer.GetAllBoundingBoxes().Contains(boundingBox))
                    boundingBoxDrawer.RemoveBoundingBox(boundingBox);
                else
                    boundingBoxDrawer.AddBoundingBox(boundingBox);
            }
            return clickedObject;
        }
        public void RemoveObject(StaticObject addedObject)
        {
            GameEditor.World.StaticObjects.Remove(addedObject);
            var boundingBoxDrawer = (BoundingBoxDrawer)GameEditor.XnaGame.Services.GetService(typeof(BoundingBoxDrawer));
            boundingBoxDrawer.RemoveBoundingBox(addedObject.InitialBoundingBox.Transform(addedObject.WorldMatrix));
        }
        public void AddObject(StaticObject staticObject)
        {
            GameEditor.World.StaticObjects.Add(staticObject);
        }
        public StaticObject AddObject(StaticObjectInfo staticObjectInfo, Vector3 position)
        {
            StaticObject staticObject;
            if (string.IsNullOrEmpty(staticObjectInfo.InheritFrom))
                staticObject = new StaticObject();
            else
            {
                Type type = Type.GetType(staticObjectInfo.InheritFrom,true);
                staticObject = (StaticObject) Activator.CreateInstance(type);
            }
            staticObject.Translation = position;
            staticObject.LoadModel(GameEditor.XnaGame, staticObjectInfo.AssetName);
            GameEditor.World.StaticObjects.Add(staticObject);
            return staticObject;
        }
        public Vector3? IntersectCursor(Point mousePos)
        {
            var cursorRay = GetCursorRay(mousePos);
            Vector3? collisionPos = GameEditor.World.IntersectWithTerrain(cursorRay);
            return collisionPos;
        }      
        public void AddObject(StaticObjectInfo staticObjectInfo, Point mousePos)
        {
            Ray cursorRay = MathHelperEx.GetCursorRay(mousePos,
                                                      GameEditor.XnaGame.GraphicsDevice.Viewport,
                                                      GameEditor.World.ProjMatrix,
                                                      GameEditor.World.ViewMatrix,
                                                      Matrix.Identity);
            Vector3? collisionPos = GameEditor.World.IntersectWithTerrain(cursorRay);
            if (collisionPos != null)
            {
                StaticObject staticObject = new StaticObject();
                staticObject.Translation = collisionPos.Value;
                staticObject.LoadModel(GameEditor.XnaGame, staticObjectInfo.AssetName);
                GameEditor.World.StaticObjects.Add(staticObject);
            }
        }

        #endregion

        #region Private Methods

        private Ray GetCursorRay(Point mousePos)
        {
            Ray cursorRay = MathHelperEx.GetCursorRay(mousePos,
                                                      GameEditor.XnaGame.GraphicsDevice.Viewport,
                                                      GameEditor.World.ProjMatrix,
                                                      GameEditor.World.ViewMatrix,
                                                      Matrix.Identity);
            return cursorRay;
        }

        #endregion
  
        #region Properties

        public IGameEditor GameEditor { get; private set; }

        #endregion
     
    }
}
